home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-10-29 | 34.5 KB | 1,372 lines |
- ;----------------------------------------------------------------
- ; COLRBOOT.A86 - Puts a color message on last four sectors of disk
- ; and rewrites sector so message will display if the disk is booted.
- ; For A86V371 assembler 28 July 1994
- ; Revised for text 3 August 1994
- ; Minor revision 27 October 1994
-
- ; This will assemble with A86 VERSION 3.71
- ; A86 COLRBOOT.A86
-
- ; JIM TUCKER 4/635 Brighton Road, Seacliff
- ; South Australia, AUSTRALIA 5051 Phone: 61 8 377-1175
- ; jtucker@adam.com.au
-
- ;----------------------------------------------------------------
-
- lf equ 10
- cr equ 13
- eom equ '$'
-
- ; BIOS LOADS BOOT SECTOR Entry:
- ; CS:IP - 0:7C00h
- ; DL - boot drive
- ; ES:SI - Ptr to partition table boot entry (if hard disk)
- ; All other registers undefined
-
- bytes_per_sec equ word ptr [bp+0bh]
- sec_per_cluster equ byte ptr [bp+0dh]
- reserved_sec equ word ptr [bp+0eh]
- number_of_fats equ byte ptr [bp+10h]
- root_size equ word ptr [bp+11h]
- total_sec equ word ptr [bp+13h]
- media_des_byte equ byte ptr [bp+15h]
- sec_per_fat equ word ptr [bp+16h]
- sec_per_track equ word ptr [bp+18h]
- number_of_heads equ word ptr [bp+1ah]
- num_hidden_sec equ word ptr [bp+1ch]
- total_sec_long equ word ptr [bp+20h]
- drive_number equ word ptr [bp+24h]
- reserved equ word ptr [bp+25h]
- extended_flag equ word ptr [bp+26h]
- vol_serial equ word ptr [bp+27h]
- vol_name equ word ptr [bp+2bh]
- boot_flag equ word ptr [bp+3feh] ;OFFSET+512 for code
-
- reloc_entry equ OFFSET boot_2 - 100h
- boot_hard_msg equ 7900h + OFFSET hard_msg
- boot_floppy_msg equ 7900h + OFFSET floppy_msg
- boot_halt_msg equ 7900h + OFFSET halt_msg
-
- ;--------------------------------------------------------------------
- ; Boot sector code. The existing BPB on the target disk is written here.
- ; The target disk *must* be DOS formatted to obtain this information.
- ;--------------------------------------------------------------------
-
- org 100h
- ENTRY: jmp signon ;becomes jmp boot_1
- BOOT_DATA db 0 ;NZ to prevent UNREG msg
- db 63 dup (0) ;leave room for BPB
- BOOT_DATAEND = $
-
- BOOT_1: cli
- cld
- mov ax,7A00h
- xor bx,bx
- mov ss,bx ;SS:SP = 0:7A00
- mov sp,ax
- sti
- push si
- push bp
- mov bp,ax ;BP is new location
-
- ; This moves all code from 7A00 to 7C00h and jumps to BOOT_2 via RETF
-
- mov ds,bx ;DS = 0
- mov es,bx ;ES = 0
- mov di,ax ;Move boot code
- mov si,7C00h
- mov cx,100h
- rep movsw
-
- push es ;Push re-entry segment
- mov al,reloc_entry ; BOOT2 OFFSET on stack
- push ax ; and go there...
- retf
-
- ; The code is moved and we read the message to location 8000h
- ; Note MESG_LOC is the cluster number changed by installation for disk
- ; sizes other than 1.44M. (1.44 last sctr=2879, we use last eight sectors).
-
- BOOT_2: db 0B8h ;mov ax imm16 instruction
- MESG_LOC dw 2870 ;changes with disk size
- SKIP_MESG: jmp >l1 ;*** NOPPED BY AUTOBOOT
- jmp test_hard ; AND NOFILE
-
- L1: call maths ;do disk sums
- mov bx,8000h ;where to put it
-
- ; This tries to read our message file (five times)
-
- mov si,5
- L1: mov dl,0 ;drive zero
- mov ax,0208h ;read eight sectors
- int 13h
- jnc done
- xor ax,ax
- int 13h
- dec si
- jnz l1
-
- ; Fall thru, if the read failed. We will not have the message code AAAAh
- ; and the message won't display anyway. Test for AAAAh (our code words)
- ; and if not found do not display anything. This prevents garbage
- ; display if the disk has been filled.
-
- DONE: mov si,8000h ;where it is in memry
- lodsw ;get first word
- cmp ax,0AAAAh ;us?
- je >l1 ;yes
- jmp test_hard ;no message to write
-
- ; This writes the color message direct to the screen
-
- L1: mov ah,0Fh ;get video mode
- int 10h
- push ax
- mov ah,0 ;clear screen
- int 10h ; by resetting mode
- pop ax
- cmp al,3
- mov ax,0B800h
- jbe >l1
- mov ah,0B0h ;(al is already zero)
- L1: push es ;get screen segment in es
- mov es,ax
- xor di,di
- push di
- pop ds
- mov cx,25*80 ;screen size
- repnz movsw
- pop es
-
- ; Note CURPOS can be modified on the command line by /Pnn
-
- db 0B6h ;mov dh imm8 instruction
- CURPOS db 21 ;cursor line (Starts at 0)
- mov dl,0 ; and column
- mov bh,dl ;video page zero
- mov ah,2 ;position cursor
- int 10h
-
- TEST_HARD: mov ah,10h ;test for hard disk
- mov dl,80h ;first disk only
- int 13h ;if exist
- jc >l4 ;not found
-
- ; Note if the following JMP is nopped by installer we boot immediately
- ; from the hard drive.
-
- BOOT_C: jmp >l9 ;** NOPPED for autoboot
- push bp
- jmp boot_hard
-
- L9: push bp
- mov ah,0
- int 1ah
- db 81h,0C2h ;add dx imm16 opcode
- TIMER_WORD dw 0 ;default = 1/18th secs
- inc dx ;in case he makes it zero
- ; and clocks rolls over
- mov bx,dx ; during this op
- L2: int 1ah
- cmp dx,bx
- jne l2
-
- mov si,boot_hard_msg ;wanna boot it?
- call bprint_msg
-
- L21: mov ah,1 ;clear kboard buffer
- int 16h ; in case he hit keys
- jz >l3 ; during time delay
- xor ah,ah ;ah=0
- int 16h
- jmp l21
-
- L3: xor ah,ah ;BIOS get key
- int 16h
- or al,20h
- cmp al,'y'
- je boot_hard ;yes
- cmp al,'n'
- jne l3
-
- ; Fall thru to boot from floppy
-
- L4: mov si,boot_floppy_msg ;wants floopy boot
- call bprint_msg
- mov ah,0 ;wait for a key
- int 16h
- call clear_screen
- int 19h ;warm boot
-
- ; This reads drive C: sector zero into 7C00h and jumps there
-
- BOOT_HARD: call clear_screen
- pop bp
- call boot_read_disk
- jc boot_error
-
- cmp boot_flag,0AA55h ;Check for boot sig
- jne boot_error
- pop bp ;Restore BP from entry
- pop si ; Is BP for DR-DOS only?
- jmp bx ;Jump to new boot rec
-
- ;Clear the screen
-
- CLEAR_SCREEN: mov ah,0Fh ;get video mode
- int 10h
- mov ah,0 ;set video mode
- int 10h
- ret
-
- BOOT_ERROR: mov si,boot_halt_msg ;Print err message
- BOOT_ERROR1: call bprint_msg
- BOOT_HALT: jmp boot_halt ;STOP!
-
- ;-----------------------------------------------------------------------
- ; BOOT_READ_DISK: Reads one sector from the hard disk
- ; CF - Clear if read successful.
- ;-----------------------------------------------------------------------
-
- BOOT_READ_DISK: xor ax,ax ;Read boot sector
- call maths
- mov bx,7C00h ;where to put it
-
- L1: mov dl,80H ;80h is first hard disk
- mov ax,0201h ;read one sector
- int 13h
- jnc ret ;no error, exit
- xor ax,ax ;reset disk before reading
- int 13h
- dec si
- jnz l1
- mov si,boot_halt_msg ;read error message
- stc
- ret
-
- ; This does some calculations common to both disk reads
-
- MATHS: cwd
- div sec_per_track
- inc dx
- mov bx,dx
- cwd
- div number_of_heads
- xchg ah,al
- mov cl,6
- shl al,cl
- xchg cx,ax
- or cl,bl
- mov dh,dl
- mov si,5
- ret
-
- ;--------------------------------------------------------------------
- ; BPRINT_MSG: - Prints a message to the screen
- ; Entry: DS:SI - Points to ASCIIZ message
- ;--------------------------------------------------------------------
-
- BPRINT_MSG: push bx
- push bp
- L1: lodsb
- or al,al
- je >l2
- mov ah,0eh
- mov bx,7h
- push si
- int 10h
- pop si
- jmp l1
- L2: pop bp
- pop bx
- ret
-
- HALT_MSG db 'CANNOT BOOT - SYSTEM HALTED ',0
- FLOPPY_MSG db cr,lf
- db 'Non-System disk. Replace and ',cr,lf
- db 'press any key when ready ',0
- HARD_MSG db 'Boot from hard disk (Y/N)? ',0
-
- BOOTCODE_END = $
- SPARE_DATA = 2FEh-BOOTCODE_END
- db spare_data dup ' '
- org 2FEh
- dw 0AA55h
-
- ;****************************************************************
- ; START OF INSTALLATION CODE
- ;****************************************************************
-
- IBM_SYS db 'A:IBMBIO.COM',0
- MS_SYS db 'A:IO.SYS',0
- AUTOBOOT db 'AUTOBOOT',0
- NOFILE db 'NOFILE',0
- BLANK db 'BLANK',0
- TARGET_DISK db 0
- REGISTER_BYTE db ?
- VIDEO_SEG dw 0B800h
- OLD_VIDEO_SEG dw 0B800h
- MONO_SWITCH db 0
- VIDEO_MODE db ?
-
- SIGNON: mov dx,OFFSET hello
- mov ah,9
- int 21h
-
- call clear_buffers ;intialise to zero
- call cmdline ;sort it out
- call check_register ;/R to prevent display
- call check_video ;/M for mono?
- call check_curpos ;see if cursor positioned
- call check_timer ;see if timer set
- call check_color ;see if color for text
- call check_filename ;want it displayed?
- call read_file1 ;check the filename etc
- call read_file2 ;read text file if any
- call get_target ;handle A: or B:
- call check_sys ;ensure not a system disk
- call get_size ;how big is it?
- call verify ;check sectors are free
- call write_message ;write our message
- call write_boot ;write the boot sector
-
- mov dx,OFFSET done_message
- mov ah,9
- int 21h
- mov ax,4C00h
- int 21h
-
- ;----------------------------------------------------------------
- ; Clears buffers to zero bytes
- ;----------------------------------------------------------------
-
- CLEAR_BUFFERS: mov di,TEXT_FILE_BUFFER
- mov ax,0
- mov cx,1000
- rep stosw
- mov ah,[103h]
- mov register_byte,ah
- ret
-
- ;----------------------------------------------------------------
- ; Check registered
- ;----------------------------------------------------------------
-
- CHECK_REGISTER: mov si,OFFSET switch_buffer
- L2: lodsb
- L3: or al,al ;end
- jz ret ;yes
- cmp al,'/' ;switch
- jne l2 ;no
- lodsb ;get
- cmp al,'R' ;us?
- jne l3 ;no, maybe zero
- mov register_byte,1 ;set reg byte
- ret
-
- ;----------------------------------------------------------------
- ; CHECK_VIDEO: This checks if user wants mono display
- ;----------------------------------------------------------------
-
- CHECK_VIDEO: mov ah,0Fh ;get current mode
- int 10h ;video
- mov video_mode,al ;save current mode
- cmp al,7 ;is it mono?
- jne >l1 ;no
- mov ax,0B000h
- mov video_seg,ax ;change seg
- mov old_video_seg,ax
-
- L1: mov si,OFFSET switch_buffer
- L2: lodsb
- L3: or al,al ;end
- jz ret ;yes
- cmp al,'/' ;switch
- jne l2 ;no
- lodsb ;get
- cmp al,'M' ;us?
- jne l3 ;no, maybe zero
- mov mono_switch,1 ;set mono switch
- ret
-
- ;----------------------------------------------------------------
- ; CHECK_CURPOS: This checks for optional cursor position /Pnn
- ;----------------------------------------------------------------
-
- TEN dw 10
- CHECK_CURPOS: mov si,OFFSET switch_buffer
- L1: lodsb ;get
- L2: or al,al ;done?
- jz ret ;yes
- cmp al,'/' ;switch?
- jne l1 ;no
- lodsb ;get
- cmp al,'P' ;us?
- jne l2 ;no, maybe zero
-
- mov al,[si] ;get next
- or al,al ;zero
- jz bad_curpos ;error
- cmp al,'=' ;=?
- jne >l2 ;no, assume digit
- inc si ;scrub it
-
- L2: xor ax,ax ;arithmetic
- xor bx,bx
- xor dx,dx
-
- L3: mov bl,[si]
- or bl,bl
- jz >l4
- cmp bl,'/'
- je >l4
-
- inc si
- sub bl,'0'
- jc bad_curpos
- cmp bl,9
- ja bad_curpos
- mul ten
- add ax,bx
- jmp l3
-
- L4: dec al
- mov curpos,al
- ret
-
- BAD_CURPOS: mov dx,OFFSET bad_curpos_mesg
- jmp error_message
-
-
- ;----------------------------------------------------------------
- ; CHECK_TIMER: This checks for optional time out /Tnn
- ;----------------------------------------------------------------
-
- TICKS_PER_SEC dw 18
- CHECK_TIMER: mov si,OFFSET switch_buffer
- L1: lodsb ;get
- L2: or al,al ;done?
- jz ret ;yes
- cmp al,'/' ;switch?
- jne l1 ;no
- lodsb ;get
- cmp al,'T' ;us?
- jne l2 ;no, maybe zero
-
- mov al,[si] ;get next
- or al,al ;zero
- jz bad_timer ;error
- cmp al,'=' ;=?
- jne >l2 ;no, assume digit
- inc si ;scrub it
-
- L2: xor ax,ax ;arithmetic
- xor bx,bx
- xor dx,dx
-
- L3: mov bl,[si]
- or bl,bl
- jz >l4
- cmp bl,'/'
- je >l4
-
- inc si
- sub bl,'0'
- jc bad_timer
- cmp bl,9
- ja bad_timer
- mul ten
- add ax,bx
- jmp l3
-
- L4: cmp ax,60
- jbe >l5
- mov dx,OFFSET too_long_mesg
- jmp error_message
- L5: mul ticks_per_sec
- mov timer_word,ax
- ret
-
- BAD_TIMER: mov dx,OFFSET bad_timer_mesg
- jmp error_message
-
- ;----------------------------------------------------------------
- ; CHECK_COLOR: This tests for option text color in hex
- ;----------------------------------------------------------------
-
- SIXTEEN dw 16
- CHECK_COLOR: mov si,OFFSET switch_buffer
- L1: lodsb ;get char
- L2: or al,al ;end?
- jz ret ;yes
- cmp al,'/' ;switch?
- jne l1 ;no
- lodsb ;get next
- cmp al,'C' ;us?
- jne l2 ;no
-
- mov al,[si] ;next
- or al,al ;end?
- jz show_colors ;yes
- cmp al,'=' ;this?
- jne >l2 ;no, assume digit
- inc si ;lose it
-
- L2: xor ax,ax ;arithmetic
- xor bx,bx
- xor dx,dx
-
- L3: mov bl,[si]
- or bl,bl
- je >l5
- cmp bl,'/'
- je >l5
-
- inc si
- xchg ax,bx
- call caps
- xchg bx,ax
-
- sub bl,'0'
- jc show_colors
- cmp bl,9
- jbe >l4
-
- sub bl,7
- jc show_colors
- cmp bl,15
- ja show_colors
-
- L4: mul sixteen
- add ax,bx
- jmp l3
-
- L5: or ax,ax
- jz show_colors
- or dx,dx
- jnz show_colors
- or ah,ah
- jnz show_colors
-
- mov text_color,al
- ret
-
- SHOW_COLORS: jmp display_color_help
-
- ;----------------------------------------------------------------
- ; CHECK_FILENAME: This checks if user want filenames displayed
- ;----------------------------------------------------------------
-
- FILENAME_SWITCH db 0
-
- CHECK_FILENAME: mov si,OFFSET switch_buffer
- L1: lodsb
- cmp al,0
- je ret
- cmp al,'/'
- jne l1
- lodsb
- cmp al,'F'
- jne l1
-
- mov filename_switch,1
- ret
-
- ;----------------------------------------------------------------
- ; READ_FILE1: This reads the user file specified on the command line
- ; If AUTOBOOT NOFILE or BLANK set NOPs in boot sector
- ;----------------------------------------------------------------
-
- LENGTH dw ?
- READ_FILE1: test W filename1
- if z jmp help ;no file
-
- ; This checks for AUTOBOOT
-
- mov si,filename1
- mov di,OFFSET autoboot
- mov cx,8
- L1: cmpsb
- jne >l2
- loop l1
- mov di,OFFSET boot_c ;NO PROMPT FOR C
- mov ax,9090h ;NOP NOP
- stosw
- mov di,OFFSET skip_mesg ;NO MESSAGE DISPLAY
- stosw ;NOP NOP
- mov W signature,0
- test B drive1
- if z jmp help
- ret
-
- ; This checks for NOFILE
-
- l2: mov si,filename1
- mov di,OFFSET nofile
- mov cx,6
- L3: cmpsb
- jne >l4
- loop l3
- mov di,OFFSET skip_mesg ;NO MESSAGE DISPLAY
- mov ax,9090h ;NOP NOP
- stosw
- mov W signature,0
- test B drive1
- if z jmp help
- ret
-
- ; This checks for BLANK
-
- l4: mov si,filename1
- mov di,OFFSET blank
- mov cx,5
- L5: cmpsb
- jne >l1
- loop l5
-
- mov di,COLOR_FILE_BUFFER
- mov cx,2000
- mov ah,text_color
- mov al,20h
- rep stosw
- jmp >l0
-
- ; No AUTOBOOT, NOFILE, BLANK so we must have a filename
-
- L1: mov dx,filename1 ;open
- mov ax,3D00h
- int 21h
- jnc >l2
- mov dx,OFFSET no_file_mesg
- jmp error_message
-
- L2: mov bx,ax ;get length
- mov ax,4202h
- mov cx,0
- mov dx,0
- int 21h
- mov length,ax
- jnc >l3
- mov dx,OFFSET bad_size_mesg
- jmp error_message
-
- L3: cmp ax,4000 ;test length
- je >l4
- mov dx,OFFSET bad_size_mesg
- jmp error_message
-
- L4: mov ax,4200h ;rewind it
- mov cx,0
- mov dx,0
- int 21h
-
- mov ax,3F00h ;read file
- mov cx,length
- mov dx,COLOR_FILE_BUFFER
- int 21h
- jnc >l5
- mov dx,OFFSET read_err_mesg
- jmp error_message
-
- L5: mov ah,3Eh ;close file
- int 21h
-
- ; Now insert the prompt blanks on the color screen
-
- L0: mov ah,0 ;put the prompt at /P
- mov al,curpos
- cmp al,24 ;0-24
- ja >l3 ;off the screen
-
- mov cl,al
- xor dx,dx
- mov bx,160 ;bytes per line
- mul bx
- mov di,ax ;is here
- add di,COLOR_FILE_BUFFER
-
- mov ax,0720h
- cmp cl,24 ;remember 0-24
- je >l2 ;just do one
- cmp cl,23 ;two to do?
- je >l1 ;yes
-
- mov cx,30
- rep stosw
- add di,100
-
- L1: mov cx,30
- rep stosw
- add di,100
-
- L2: mov cx,30
- rep stosw
-
- L3: mov dx,OFFSET reading_mesg
- call print_message
- ret
-
- ;----------------------------------------------------------------
- ; READ_FILE2: This reads the SECOND file if specified
- ;----------------------------------------------------------------
-
- GRID_NAME db 'GRID',0
- READ_FILE2: test W filename2
- jz ret ;there isn't one
-
- ; Test if he is requesting a grid
-
- mov si,filename2
- mov di,OFFSET grid_name
- mov cx,4
- L1: cmpsb
- jne >l2
- loop l1
- jmp write_grid
-
- L2: mov dx,filename2 ;open file
- mov ax,3d00h
- int 21h
- jnc >l1
- mov dx,OFFSET no_text_mesg
- jmp error_message
-
- L1: mov bx,ax ;get length
- mov ax,4202h
- mov cx,0
- mov dx,0
- int 21h
- mov length,ax
- jnc >l2
- mov dx,OFFSET bad_size_mesg
- jmp error_message
-
- L2: cmp ax,2000 ;test for size
- jbe >l3
- mov dx,OFFSET bad_size_mesg2
- jmp error_message
-
- L3: mov ax,4200h ;rewind it
- mov cx,0
- mov dx,0
- int 21h
-
- mov ax,3F00h ;read file
- mov cx,length
- mov dx,TEXT_FILE_BUFFER
- int 21h
- jnc >l4
- mov dx,OFFSET read_err_mesg
- jmp error_message
-
- L4: mov ah,3eh ;close file
- int 21h
-
- mov dx,OFFSET reading_mesg2
- call print_message
- jmp overlay_text
-
- ; Now lay it on top of the color message
-
- LINE_NUMBER dw 0
- BYTES_PER_LINE dw 160
- PROMPT_FLAG db 0 ;this is set if writing
- TEXT_COLOR db 07h ;set by /Cnn switch
- CHAR_COUNT db 0 ;so we don't bust a line
-
- WRITE_GRID: mov si,OFFSET grid ;lay down the grid
- call overlay ;and come back for prompt
-
- WRITE_PROMPT: mov ah,0 ;put the prompt
- mov al,curpos ; according to /P
- dec ax ;prompt starts with a cr
- mov line_number,ax ;force it here
- inc prompt_flag
- mov si,OFFSET grid_prompt ;source
- jmp overlay ;and return to main
-
- OVERLAY_TEXT: mov si,TEXT_FILE_BUFFER
- OVERLAY: mov di,COLOR_FILE_BUFFER
-
- L1: lodsb ;get char from text buffer
- cmp al,cr ;new line?
- je >l3 ;yes
- cmp al,lf ;ignore lf
- je l1
- cmp al,0 ;end of it?
- je ret
-
- cmp al,'_'
- jne >l2
- add di,2
- jmp l1
-
- L2: inc char_count
- cmp char_count,80
- ja l1
-
- stosb ;save it
- mov al,text_color ;make it /Cnn
- test prompt_flag ;unless it's the prompt...
- jz >l21
- mov al,07h
- L21: stosb
- jmp l1 ;do more
-
- L3: mov char_count,0
- inc line_number ;new line
- mov ax,line_number ;here
- cmp ax,25 ;past end?
- ja ret
- mul bytes_per_line ;position of next line
- mov di,ax ;is here
- add di,COLOR_FILE_BUFFER
- jmp l1 ;do more
- ret
-
- ;----------------------------------------------------------------
- ; GET_TARGET: This puts the target drive in TARGET_DISK and IO NAMES
- ; Return if A: (default) or error if <> B:
- ;----------------------------------------------------------------
-
- GET_TARGET: mov al,drive1 B
- test al
- if z jmp display_file
- cmp al,'A'
- je ret
- cmp al,'B'
- je >l1
- mov dx,OFFSET bad_target_mesg
- jmp error_message
-
- L1: mov target_disk,1
- mov ibm_sys,'B'
- mov ms_sys,'B'
- ret
-
- ;----------------------------------------------------------------
- ; CHECK_SYS: This checks if system is on the target disk by trying
- ; to open two files.
- ;----------------------------------------------------------------
-
- CHECK_SYS: mov dx,OFFSET target_mesg
- call print_message
-
- mov dx,OFFSET ibm_sys ;check for ibmio.com
- mov ax,3D00h
- int 21h
- jnc >l1
- mov dx,OFFSET ms_sys ;check for io.sys
- mov ax,3D00h
- int 21h
- jc ret
- L1: mov dx,OFFSET system_mesg
- jmp error_message
- ret
-
- ;----------------------------------------------------------------
- ; GET_SIZE: This establishes the size of the target disk and the
- ; sector we will use for the color message
- ;----------------------------------------------------------------
-
- GET_SIZE: mov dl,target_disk
- inc dl
- mov ah,36h
- int 21h
- mov bx,dx
- xor dx,dx ;sec per cluster
- mul cx ;times bytes per sec
- cmp dx,0
- jne size_error
- mul bx ;number of clusters
-
- add ax,dx ;ah=ax al=dx
- cmp ax,3E16h ;ie 0016:3E00=1457664
- je size_144
- cmp ax,240Bh
- je size_720
- cmp ax,8805h
- je size_360
- cmp ax,8612h
- je size_12
-
- SIZE_ERROR: mov dx,OFFSET wrong_disk_mesg
- jmp error_message
-
- SIZE_144: mov dx,OFFSET size_144_mesg ;2870 already there
- jmp >l1
- SIZE_720: mov mesg_loc,1360
- mov dx,OFFSET size_720_mesg
- jmp >l1
- SIZE_360: mov mesg_loc,710
- mov dx,OFFSET size_360_mesg
- jmp >l1
- SIZE_12: mov mesg_loc,2390
- mov dx,OFFSET size_12_mesg
-
- L1: call print_message
- ret
-
- ;----------------------------------------------------------------
- ; VERIFY: Sends a warning message if data .ne. F6h on target sector
- ; by doing an absolute read to the sector
- ;----------------------------------------------------------------
-
- VERIFY: mov ax,signature W
- cmp ax,0AAAAh
- jne ret
-
- mov al,target_disk
- mov cx,1
- mov dx,mesg_loc
- mov bx,VERIFY_BUFFER
- int 25h
- pop bx ;stack garbage
- jnc >l1
- call seterrmsg
- jmp init_error
-
- L1: mov si,VERIFY_BUFFER
- lodsw
- cmp ax,0F6F6h
- je ret
-
- mov dx,OFFSET verify_mesg ;want to continue?
- call print_message
- L2: mov ah,8 ;wait for a key
- int 21h
- or al,20h
- cmp al,'y'
- je ret
- cmp al,'n'
- jne l2
- mov dx,OFFSET abort_mesg
- jmp error_message
-
- ;----------------------------------------------------------------
- ; WRITE_MESSAGE: This writes the message to the disk unless the
- ; signature has been zapped
- ;----------------------------------------------------------------
-
- UNREG_MSG db ' '-64,'U'-64,'N'-64,'R'-64,'E'-64,'G'-64,'I'-64
- db 'S'-64,'T'-64,'E'-64,'R'-64,'E'-64,'D'-64,' '-64
-
- WRITE_MESSAGE:
-
- ; THIS WRITES AN UNREGISTERED MESSAGE
-
- test register_byte
- jnz >l2
-
- mov di,OFFSET signature
- add di,4000-26
- mov ah,01Eh+80h
- mov bx,OFFSET UNREG_MSG
- mov cx,14
- L1: mov al,[bx]
- inc bx
- add al,64
- stosw
- loop l1
-
- L2: mov ax,signature W
- cmp ax,0AAAAh
- jne ret
-
- mov al,target_disk
- mov cx,8 ;8 sectors
- mov dx,mesg_loc
- mov bx,OFFSET signature
- int 26h ;DOS Absolute Disk Write
- pop bx ;stack shit
- jnc ret ;done
- call seterrmsg
- jmp init_error
-
- ;--------------------------------------------------------------------
- ; WRITE_BOOT: - Installs our boot record on the target diskette
- ; Exit: CF - Set if error
- ; DX - OFFSET of error message if CF set
- ;--------------------------------------------------------------------
-
- WRITE_BOOT: mov dx,OFFSET install_mesg
- call print_message
-
- ; This writes a new jump at start of our boot sector (100h)
-
- mov di,OFFSET entry
- mov al,0E9h ;JMP short opcode
- stosb
- mov ax,OFFSET boot_1-OFFSET boot_data
- stosw
-
- ; Read the boot sector from the target disk into a buffer
-
- mov al,target_disk ;Get target disk
- mov cx,1 ;read 1 sector
- xor dx,dx ;Sector 0
- mov si,dx
- mov bx,TARGET_BOOT_SECTOR
- call read_absolute
- jc install_error
-
- ; This checks the JMP (short or long according to DOS version).
-
- mov si,bx ;point to boot rec
- lodsb ;get opcode
- mov dl,al
- lodsw ;get where to
- mov bx,si ;next address
- cmp dl,0EBh ;short JMP?
- jne >l1 ;no
- xor ah,ah ;if short JMP clear
- jmp >l2 ; high byte
-
- L1: cmp dl,0E9h ;Check for long JMP
- je >l2
- mov dx,OFFSET not_dos_mesg
- jmp error_message
-
- L2: mov dx,OFFSET cant_write_mesg
- dec ax
- cmp ax,OFFSET boot_dataend - OFFSET entry
- if a jmp error_message
-
- ; This copies the boot data from target disk to our boot
-
- mov si,bx
- mov di,OFFSET boot_data ;copy boot data to
- mov cx,ax ; boot rec
- rep movsb
-
- ; This writes the boot sector to the target disk
-
- mov al,target_disk ;Get target disk
- mov bx,OFFSET entry
- mov cx,1 ;1 sector
- xor dx,dx ;Sector 0
- xor si,si
- call write_absolute ;Write new boot rec
- jc install_error
- ret
-
- INSTALL_ERROR: call seterrmsg
- INIT_ERROR: call print_msg
- mov ax,4C01h
- int 21h
-
- ;--------------------------------------------------------------------
- ; READ ABSOLUTE - Reads sectors from the disk.
- ; Entry: AL - Drive to read
- ; CX - Number of sectors to read.
- ; SI,DX - Sector to start read (SI only used on huge disks)
- ; DS:BX - Pointer to data buffer.
- ;--------------------------------------------------------------------
-
- READ_ABSOLUTE: push bx
- push cx
- push ds
- int 25h ;DOS Absolute Disk Read
- pop bx ;stack shit
- call seterrmsg
- cld
- pop ds
- pop cx
- pop bx
- ret
-
- ;--------------------------------------------------------------------
- ; WRITE ABSOLUTE - Writes sectors to the disk.
- ; Entry: AL - Drive to write
- ; CX - Number of sectors to write
- ; SI,DX - Sector to start write (SI only used on huge disks)
- ; DS:BX - Pointer to data buffer.
- ;--------------------------------------------------------------------
-
- WRITE_ABSOLUTE: push bx
- push cx
- push ds
- int 26h ;DOS Absolute Disk Write
- pop bx ;statck shit
- call seterrmsg
- cld
- pop ds
- pop cx
- pop bx
- ret
-
- ;----------------------------------------------------------------
- ; Sundry routines used by the above
- ;----------------------------------------------------------------
-
- CAPS: cmp al,'a'
- jb ret
- cmp al,'z'
- ja ret
- and al,5Fh
- ret
-
- PRINT_MESSAGE: push ax
- mov ah,9
- int 21h
- pop ax
- ret
-
- HELP: JMP DISPLAY_SCREEN
-
- ERROR_MESSAGE: call print_message
- mov ax,4C01h
- int 21h
-
- ;----------------------------------------------------------------
- ; MESSAGE DATA
- ;----------------------------------------------------------------
-
- NO_FILE_MESG db 'Color file not found',7,cr,lf,eom
- NO_TEXT_MESG db 'Text file not found',7,cr,lf,eom
- BAD_TARGET_MESG db 'Invalid target drive',7,cr,lf,eom
- SYSTEM_MESG db 'Target contains system files. Aborted.',7,cr,lf,eom
- TARGET_MESG db 'Verifying target disk',cr,lf,eom
- WRONG_DISK_MESG db 'Wrong size disk',7,cr,lf,eom
- VERIFY_MESG db 'WARNING! Message sector may contain data. Continue (Y/N)?',7,cr,lf,eom
- ABORT_MESG db 'Aborted as user request',cr,lf,eom
- SIZE_144_MESG db '1.44Mb disk detected',cr,lf,eom
- SIZE_720_MESG db '720Kb disk detected',cr,lf,eom
- SIZE_360_MESG db '360Kb disk detected',cr,lf,eom
- SIZE_12_MESG db '1.2Mb disk detected',cr,lf,eom
- READING_MESG db 'Reading color file',cr,lf,eom
- READING_MESG2 db 'Reading text file',cr,lf,eom
- BAD_SWITCH_MESG db 'Invalid switch',7,cr,lf,eom
- BAD_CURPOS_MESG db 'Invalid cursor /P position',cr,lf,eom
- BAD_TIMER_MESG db 'Invalid timer /T value',7,cr,lf,eom
- TOO_LONG_MESG db 'Timer delay must not exceed 60 seconds',7,cr,lf,eom
- BAD_COLOR_MESG db 'Invalid color /C specified',7,cr,lf,eom
- NOT_DOS_MESG db 'Target diskette not a DOS formatted disk',7,cr,lf,eom
- CANT_WRITE_MESG db 'Cannot write code on target disk',7,cr,lf,eom
- INSTALL_MESG db 'Installing boot sector',cr,lf,eom
- BAD_SIZE_MESG db 'Bad color file size (must be 4000 bytes)',7,cr,lf,eom
- BAD_SIZE_MESG2 db 'Bad text file size (maximum 2000 bytes)',7,cr,lf,eom
- READ_ERR_MESG db 'Error reading data file',7,cr,lf,eom
- WRITE_ERROR db 'Error writing data to sector address',7,cr,lf,eom
- DONE_MESSAGE db 'Disk modified OK',cr,lf,eom
-
- HELLO db cr,lf
- db 'COLRBOOT V1.0 ■ Release November 1994 JIM TUCKER',cr,lf
- db 'Copyright (c) 1994 JIM TUCKER. All rights reserved',cr,lf,eom
-
- ;----------------------------------------------------------------
- ; This is the display stuff
- ;----------------------------------------------------------------
-
- CURSOR_SIZE dw ?
- CURSOR_POS dw ?
-
- ;----------------------------------------------------------------
- ; This moves the COLOR_HELP screen to the OUTPUT screen
- ;----------------------------------------------------------------
-
- DISPLAY_COLOR_HELP:
- mov si,OFFSET color_help
- mov di,OFFSET output_screen
- mov cx,2000
- rep movsw
- jmp display_screen
-
- ;----------------------------------------------------------------
- ; This moves the FILE (and any overlay) to the OUTPUT screen
- ;----------------------------------------------------------------
-
- DISPLAY_FILE: call write_prompt ; put prompt on screen
- mov si,COLOR_FILE_BUFFER ; get the file
- mov di,OFFSET output_screen
- mov cx,2000
- rep movsw
- test filename_switch ; /F switch?
- jz display_screen ; no
-
- mov si,filename1 ; display filename
- mov di,OFFSET output_screen
- add di,4000-40
- mov ah,0Eh
- L1: lodsb
- test al
- jz display_screen
- stosw
- jmp l1
-
- ;----------------------------------------------------------------
- ; Here to display the contents of the OUTPUT screen
- ;----------------------------------------------------------------
-
- ; This saves the current screen - we can overwrite the file buffer
- ; DS:SI is the screen, ES:DI is the buffer
-
- DISPLAY_SCREEN: mov di,COLOR_FILE_BUFFER
- mov ax,video_seg ; current video
- mov ds, ax ; place in DS
- xor si, si ; zero SI
- mov cx, 2000
- rep movsw ; store chars and color
- mov ds,cs ; done, restore DS
-
- ; Save the cursor info
-
- mov bh,0 ; page zero
- mov ah,3 ; get cursor info
- int 10h
- mov cursor_pos,dx ; save it for restore
- mov cursor_size,cx
-
- ; Hide the cursor
-
- mov ah,2
- mov bh,0
- mov dx,1A00h
- int 10h
-
- test mono_switch
- jz >l1
- mov ah,0
- mov al,7
- int 10h
- mov ax,video_seg
- mov old_video_seg,ax
- mov video_seg,0B000h
-
- ; This WRITES the OUTPUT screen to the VIDEO SEGMENT
-
- L1: mov ax,video_seg
- mov es,ax
- mov si,offset OUTPUT_SCREEN
- xor di,di
- mov cx,2000
- rep movsw
- mov es,cs
-
- L1: mov ah,01h ;wait for a keystroke
- int 016h
- jz l1
- mov ah,0 ;clear keyboard buffer
- int 016h
-
- ; Restore the screen
-
- mov al,video_mode
- mov ah,0
- int 10h
- mov ax,old_video_seg
- mov video_seg,ax
-
- ; DS:SI is the buffer, ES:DI is the screen
-
- L1: mov si,COLOR_FILE_BUFFER
- mov ax,video_seg
- mov es,ax
- xor di,di
- mov cx,2000
- rep movsw
- mov es,cs
-
- ; Put the cursor back
-
- mov bh,0
- mov dx,cursor_pos
- mov ah,2
- int 10h
- mov cx,cursor_size
- mov ah,1
- int 10h
-
- mov ax,4C00h
- int 21h
-
- ;----------------------------------------------------------------
- ; The following are messages returned by absolute and read and write.
-
- DOSERR_TBL dw OFFSET doserr_00
- dw OFFSET doserr_01
- dw OFFSET doserr_02
- dw OFFSET doserr_03
- dw OFFSET doserr_04
- dw OFFSET doserr_05
- dw OFFSET doserr_06
- dw OFFSET doserr_07
- dw OFFSET doserr_08
- dw OFFSET doserr_09
- dw OFFSET doserr_10
- dw OFFSET doserr_11
- dw OFFSET doserr_12
- dw OFFSET doserr_unk
- DOSERR_TBLEND = $
-
- doserr_00 db "Disk Write Protected",0
- doserr_01 db "Unknown Unit",0
- doserr_02 db "Drive not ready",0
- doserr_03 db "Unknown Command",0
- doserr_04 db "CRC Data Error",0
- doserr_05 db "Bad request structure",0
- doserr_06 db "Disk Seek error",0
- doserr_07 db "Not a DOS disk",0
- doserr_08 db "Sector not found",0
- doserr_09 db "Printer out of paper",0
- doserr_10 db "Disk Write fault",0
- doserr_11 db "Disk Read fault",0
- doserr_12 db "General failure",0
- doserr_unk db "Unknown DOS error",0
-
- ;--------------------------------------------------------------------
- ; SETERRMSG: Assigns a DOS error message to the value in AL
- ; Entry: AL - Error code
- ; CF - Set if error
- ; Exit: SI - Points to error message
- ;--------------------------------------------------------------------
-
- SETERRMSG: push bx
- pushf
- jnc >l2
- mov bx,ax
- xor bh,bh
- shl bx,1
- cmp bx,OFFSET doserr_tblend - OFFSET doserr_tbl
- jbe >l1
- mov bx,26
- L1: mov si,[bx+doserr_tbl]
- L2: popf
- pop bx
- ret
-
- ;----------------------------------------------------------------
- ; PRINT_MSG: Prints ASCIIZ message to screen appending crlf
- ; Entry: DS:SI - Points to ASCIIZ message
- ;----------------------------------------------------------------
-
- CRLF_MSG db 13,10,0
- PRINT_MSG: call print_line
- mov si,OFFSET crlf_msg
- call print_line
- ret
-
- ;----------------------------------------------------------------
- ; PRINT_LINE: Prints a line to the screen
- ; Entry: DS:SI - Points to ASCIIZ message
- ;----------------------------------------------------------------
-
- PRINT_LINE: lodsb
- or al,al
- je >l1
- mov dl,al
- mov ah,02
- int 21h
- jmp short print_line
- L1: ret
-
- ; If you do not have the latest version of A86 catenate these files
- ; to this file.
-
- INCLUDE CMDLINE.A86
- INCLUDE CBDATA.A86
-
- ; END COLRBOOT.A86
-